gh-151039: Fix a crash when _datetimetypes outlive _datetime module#151044
Conversation
|
Ok, I just discovered #132413 which is related. |
…Z0qBn.rst Co-authored-by: Stan Ulbrych <stan@python.org>
datetime.timedelta outlives _datetime module_datetimetypes outlive _datetime module
|
Can you change Detailsdiff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index eb05539d4c2..efc81538e38 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -126,8 +126,8 @@ get_module_state(PyObject *module)
#define INTERP_KEY ((PyObject *)&_Py_ID(cached_datetime_module))
-static PyObject *
-get_current_module(PyInterpreterState *interp)
+static int
+get_current_module(PyInterpreterState *interp, PyObject **p_mod)
{
PyObject *mod = NULL;
@@ -151,11 +151,14 @@ get_current_module(PyInterpreterState *interp)
Py_DECREF(ref);
}
}
- return mod;
+ *p_mod = mod;
+ assert(!PyErr_Occurred());
+ return (mod != NULL);
error:
assert(PyErr_Occurred());
- return NULL;
+ *p_mod = mod;
+ return -1;
}
static PyModuleDef datetimemodule;
@@ -164,11 +167,11 @@ static datetime_state *
_get_current_state(PyObject **p_mod)
{
PyInterpreterState *interp = PyInterpreterState_Get();
- PyObject *mod = get_current_module(interp);
+ PyObject *mod;
+ if (get_current_module(interp, &mod) < 0) {
+ goto error;
+ }
if (mod == NULL) {
- if (PyErr_Occurred()) {
- goto error;
- }
/* The static types can outlive the module,
* so we must re-import the module. */
mod = PyImport_ImportModule("_datetime");
@@ -7610,8 +7613,8 @@ _datetime_exec(PyObject *module)
datetime_state *st = get_module_state(module);
PyInterpreterState *interp = PyInterpreterState_Get();
- PyObject *old_module = get_current_module(interp);
- if (PyErr_Occurred()) {
+ PyObject *old_module;
+ if (get_current_module(interp, &old_module) < 0) {
assert(old_module == NULL);
goto error;
} |
vstinner
left a comment
There was a problem hiding this comment.
LGTM. Removing the PyErr_Occurred() call may make the code a little bit faster. But the new get_current_module() API is also easier to follow.
StanFromIreland
left a comment
There was a problem hiding this comment.
LGTM, with Victor's and my patches.
|
Thanks @sobolevn for the PR 🌮🎉.. I'm working now to backport this PR to: 3.13, 3.14, 3.15. |
|
Sorry, @sobolevn, I could not cleanly backport this to |
|
GH-151143 is a backport of this pull request to the 3.15 branch. |
|
GH-151144 is a backport of this pull request to the 3.14 branch. |
|
3.13 has a completely different code, I would prefer not to touch it, if possible. |
|
I can reproduce the crash on 3.13. But I'm fine with not backporting the change to 3.13. This |
Several changes:
GET_CURRENT_STATEcan returnNULL(void)PyWeakref_GetRefcall into a full check for safety, there are multiple things that can go wrong when getting a weakrefassert(!PyErr_Occurred());followed byif (PyErr_Occurred()) {